package com.moody.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.moody.hibernate.dao.ClassifyRecordDAO;
import com.moody.hibernate.dao.CollateralInfoDAO;
import com.moody.hibernate.dao.CustDefaultEventDAO;
import com.moody.hibernate.dao.DebtCollateralDAO;
import com.moody.hibernate.dao.DebtInfoDAO;
import com.moody.hibernate.dao.DebtInfoDAO;
import com.moody.hibernate.dao.GuaranteeInfoDAO;
import com.moody.hibernate.dao.GuarantorInfoDAO;
import com.moody.hibernate.dao.PdHDAO;
import com.moody.hibernate.dao.UserRoleDAO;
import com.moody.hibernate.domain.ClassifyRecord;
import com.moody.hibernate.domain.CollateralInfo;
import com.moody.hibernate.domain.CustDefaultEvent;
import com.moody.hibernate.domain.CustInfo;
import com.moody.hibernate.domain.DebtCollateral;
import com.moody.hibernate.domain.DebtCollateralId;
import com.moody.hibernate.domain.DebtInfo;
import com.moody.hibernate.domain.GuaranteeInfo;
import com.moody.hibernate.domain.GuaranteeInfoId;
import com.moody.hibernate.domain.GuarantorInfo;
import com.moody.hibernate.domain.PdH;
import com.moody.hibernate.domain.RoleInfo;
import com.moody.hibernate.domain.UserRole;
import com.moody.init.RoleRightInit;
import com.moody.service.CustomerService;
import com.moody.service.ObligationService;
import com.moody.service.SystemService;

/*
 * Copyright © Moody analytics
 *
 * @Author: Yan Jian
 * @Time: 2011-10-17 下午08:36:39
 * @Modified by: 
 * @Description: 
 */
@Service
public class ObligationServiceImpl implements ObligationService {
	private static final Logger log = LoggerFactory.getLogger(CustomerServiceImpl.class);
	WebApplicationContext web = ContextLoader.getCurrentWebApplicationContext();
	ServletContext context = web.getServletContext();  
	WebApplicationContext ctx  = WebApplicationContextUtils.getWebApplicationContext(context);
	Map<String,List<String>> orgMap = (Map<String, List<String>>) context.getAttribute("OrgMap");
	
	private CollateralInfoDAO collateralInfoDao = CollateralInfoDAO.getFromApplicationContext(ctx);
	private DebtCollateralDAO debtCollateralDao = DebtCollateralDAO.getFromApplicationContext(ctx);
	private ClassifyRecordDAO classifyRecordDao = ClassifyRecordDAO.getFromApplicationContext(ctx);
	private DebtInfoDAO debtInfoDao = DebtInfoDAO.getFromApplicationContext(ctx);
	private PdHDAO pdhDAO = PdHDAO.getFromApplicationContext(ctx);
	private CustDefaultEventDAO custDefaultEventDao = CustDefaultEventDAO.getFromApplicationContext(ctx);
	private GuaranteeInfoDAO guaranteeInfoDAO = GuaranteeInfoDAO.getFromApplicationContext(ctx);
	private GuarantorInfoDAO guarantorInfoDAO = GuarantorInfoDAO.getFromApplicationContext(ctx);
	
	@Resource
	private SystemService systemService;
	@Resource
	private CustomerService customerService;

	public List<CollateralInfo> findAllCollateralByInputID() {
		
		return collateralInfoDao.findAll();
	}

	public void insertCollateral(CollateralInfo collateralInfo) {
		collateralInfoDao.save(collateralInfo);
		
	}

	public CollateralInfo findCollateralById(String collateralId) {
		
		return collateralInfoDao.findById(collateralId);
	}

	public void updateCollateral(CollateralInfo collateralInfo) {
		collateralInfoDao.update(collateralInfo);
		
	}

	public void deleteCollateralById(String collateralId) {
		collateralInfoDao.deleteById(collateralId);
		
	}

	public List<DebtCollateral> findDebtCollateralByCollateralId(
			String collateralId) {
		
		return debtCollateralDao.findByCollateralId(collateralId);
	}

	@SuppressWarnings("unchecked")
	public List<DebtInfo> findDebtByCustId(String debtCustId) {
		return debtInfoDao.findByCustId(debtCustId);
	}

	public void deleteDebtById(String debtNo) {
		debtInfoDao.delete(debtInfoDao.findById(debtNo));
	}

	public void insertDebt(DebtInfo debtInfo) {
		debtInfoDao.save(debtInfo);
	}

	
	public List<ClassifyRecord> findAllClassifyRecordByAuthID(String classifyStatus,String userId,String orgId) {
		
		List<ClassifyRecord> list = classifyRecordDao.findByStatus(classifyStatus);
		return classifyRecordFilter(list,userId,orgId);
	}

	public DebtInfo findDebtInfoById(String debtNo) {
		
		return debtInfoDao.findById(debtNo);
	}

	public ClassifyRecord findClassifyRecordById(String serialNo) {
		
		return classifyRecordDao.findById(serialNo);
	}

	public void updateClassifyRecord(ClassifyRecord cr) {
		
		classifyRecordDao.update(cr);
	}

	public void updateDebtInfo(DebtInfo debt) {
		
		debtInfoDao.update(debt);
		
	}

	public List<CustDefaultEvent> findAllCustDefaultEventByAuthID(String status,String userId,String orgId) {
		List<CustDefaultEvent> list = custDefaultEventDao.findByStatus(status);
		return custDefaultEventFilter(list,userId,orgId);
	}

	public CustDefaultEvent findCustDefaultEventById(String serialNo) {
		
		return custDefaultEventDao.findById(serialNo);
	}

	public void updateCustDefaultEvent(CustDefaultEvent de) {
		
		custDefaultEventDao.update(de);
	}
	
	public List<CustDefaultEvent> findAllCustDefaultEventByCustId(String custId) {
		return custDefaultEventDao.findDEByCustId(custId);
	}

	public void insertCustDefaultEvent(CustDefaultEvent custDefaultEvent) {
		
		custDefaultEventDao.save(custDefaultEvent);
	}

	public void deleteCustDefaultEventById(String serialNo) {
		custDefaultEventDao.delete(custDefaultEventDao.findById(serialNo));
		
	}

	public void insertClassifyRecord(ClassifyRecord classifyRecord) {
		
		classifyRecordDao.save(classifyRecord);
	}

	public List<ClassifyRecord> findClassifyRecordByDebtNo(String debtNo) {
		
		return classifyRecordDao.findByDebtNo(debtNo);
	}

	public List<DebtCollateral> findDebtCollateralByDebtNo(String debtNo) {
		return debtCollateralDao.findByDebtNo(debtNo);
	}

	public void insertDebtCollateral(DebtCollateral debtCollateral) {
		debtCollateralDao.save(debtCollateral);
		
	}

	public DebtCollateral findDebtCollateralById(DebtCollateralId id) {
		return debtCollateralDao.findById(id);
	}

	public void deleteDebtCollateral(DebtCollateral debtCollateral) {
		debtCollateralDao.delete(debtCollateral);
		
	}

	public void updateDebtCollateral(DebtCollateral debtCollateral) {
		debtCollateralDao.update(debtCollateral);
		
	}

	public List<GuaranteeInfo> findDebtGuarantorByDebtNo(String debtNo) {
		return guaranteeInfoDAO.findDebtGurantorByDebtNo(debtNo);
	}

	public GuaranteeInfo findDebtGuarantorById(GuaranteeInfoId id) {
		GuaranteeInfo guaranteeInfo = guaranteeInfoDAO.findById(id);
		PdH pdh = pdhDAO.findNewestPDByCustId(id.getGuarantorId());
		if(pdh == null)return guaranteeInfo;
		
		String bdcreditLevel = pdh.getConfirmPdlevel();
		String bdcreditDate = pdh.getConfirmDate();
		
		if(bdcreditLevel == null || bdcreditDate == null){
			bdcreditLevel = "";
			bdcreditDate = "";
		}
		guaranteeInfo.setBdcreditLevel(bdcreditLevel);
		guaranteeInfo.setBdcreditDate(bdcreditDate);
		
		return guaranteeInfo;
	}

	public void insertDebtGuarantee(GuaranteeInfo guaranteeInfo) {
		guaranteeInfoDAO.save(guaranteeInfo);
	}

	public void updateDebtGuaranteeInfo(GuaranteeInfo guaranteeInfo) {
		guaranteeInfoDAO.update(guaranteeInfo);
	}

	public void deleteDebtGuaranteeById(GuaranteeInfoId id) {
		if(guaranteeInfoDAO.findById(id)!=null)
			guaranteeInfoDAO.delete(guaranteeInfoDAO.findById(id));
	}

	public void deleteDebtGuarantee(GuaranteeInfo guaranteeInfo) {
		guaranteeInfoDAO.delete(guaranteeInfo);
	}
	public Double calDebtBalanceSumByCustId(String custId){
		List<DebtInfo> diList = debtInfoDao.findByCustId(custId);
		Double debtBalanceSum = 0.0;
		for(DebtInfo di : diList){
			if(di.getDebtBalance() != null){
				debtBalanceSum += di.getDebtBalance();
			}
		}
		return debtBalanceSum;
	}
	
	private List<ClassifyRecord> classifyRecordFilter(List<ClassifyRecord> list ,String userId,String orgId){
		List<String> orgList = orgMap.get(orgId);
		List<String> orgListCopy = new ArrayList<String>();
		orgListCopy.addAll(orgList);
		List<RoleInfo> roleList = systemService.findRoleByUserId(userId);
		String accessURL = RoleRightInit.getInstance().getRightMap().get(roleList.get(0).getRoleId()).get("accessURL");
		
		//权限--资产分类初分:只能显示自己所属客户即下级机构客户的信息
		if(accessURL.contains("addClassifyRecord.do")){
		}
		//权限--资产分类认定：显示同机构及下级机构客户的信息
		else if(accessURL.contains("classifyConfirm.do")){
			orgListCopy.add(orgId);
		}
		
		Iterator<ClassifyRecord> it = list.iterator();
		while(it.hasNext()){
			ClassifyRecord cr = it.next();
			DebtInfo debt = findDebtInfoById(cr.getDebtNo());
			if(debt == null) {
				it.remove(); //债项已删除，关联未删除！哎……
				continue;
			}
			CustInfo cust = customerService.findCustByCustId(debt.getCustId());
			if(cust == null) {
				it.remove();
				continue;
			}
			String custInputUserId = cust.getInputUserId();
			String custInputOrgId = cust.getInputOrgId();
			if(!custInputUserId.equals(userId) && !orgListCopy.contains(custInputOrgId)) it.remove();
			else{

				if(cr.getFruserId() != null)cr.setFruserId(systemService.findUserById(cr.getFruserId()).getUsername());
				else cr.setFruserId(systemService.findUserById(custInputUserId).getUsername());
				if(cr.getFrorgId() != null)cr.setFrorgId(systemService.findOrgById(cr.getFrorgId()).getOrgname());
				else cr.setFrorgId(systemService.findOrgById(custInputOrgId).getOrgname());
				if(cr.getConfirmUserId() != null)cr.setConfirmUserId(systemService.findUserById(cr.getConfirmUserId()).getUsername());
				if(cr.getConfirmOrgId() != null)cr.setConfirmOrgId(systemService.findOrgById(cr.getConfirmOrgId()).getOrgname());
			}
		}
		
		return list;
	}
	
	private List<CustDefaultEvent> custDefaultEventFilter(List<CustDefaultEvent> list ,String userId,String orgId){
		List<String> orgList = orgMap.get(orgId);
		List<String> orgListCopy = new ArrayList<String>();
		orgListCopy.addAll(orgList);
		List<RoleInfo> roleList = systemService.findRoleByUserId(userId);
		String accessURL = RoleRightInit.getInstance().getRightMap().get(roleList.get(0).getRoleId()).get("accessURL");
		
		//权限--违约登记 :只能显示自己所属客户即下级机构客户的信息
		if(accessURL.contains("/obligation/addCustDefaultEvent.do")){
		}
		//权限--违约认定 ：显示同机构及下级机构客户的信息
		else if(accessURL.contains("/obligation/deConfirm.do")){
			orgListCopy.add(orgId);
		}
		
		Iterator<CustDefaultEvent> it = list.iterator();
		while(it.hasNext()){
			CustDefaultEvent custDefaultEvent = it.next();
			CustInfo cust = customerService.findCustByCustId(custDefaultEvent.getCustId());
			if(cust == null) {
				it.remove();
				continue;
			}
			String custInputUserId = cust.getInputUserId();
			String custInputOrgId = cust.getInputOrgId();
			if(!custInputUserId.equals(userId) && !orgListCopy.contains(custInputOrgId)) it.remove();
			else{
				custDefaultEvent.setInputUserId(systemService.findUserById(custInputUserId).getUsername());
				custDefaultEvent.setInputOrgId(systemService.findOrgById(custInputOrgId).getOrgname());
			}
		}
		return list;
	}

	public void insertGuarantorInfo(GuarantorInfo guarantorInfo) {
		guarantorInfoDAO.save(guarantorInfo);
	}

	@SuppressWarnings("unchecked")
	public List<GuarantorInfo> findAllGuarantor() {
		return guarantorInfoDAO.findAll();
	}

	public GuarantorInfo findGuarantorById(String guarantorId) {
		return guarantorInfoDAO.findById(guarantorId);
	}

	public void updateGurantor(GuarantorInfo guarantorInfo) {
		guarantorInfoDAO.update(guarantorInfo);
	}

	public List<GuaranteeInfo> findGuaranteeByGuarantorId(String guarantorId) {
		return guaranteeInfoDAO.findGuaranteeByGuarantorId(guarantorId);
	}

	public void deleteGuarantorById(String guarantorId) {
		guarantorInfoDAO.delete(guarantorInfoDAO.findById(guarantorId));
	}


	public boolean hasUsed(String debtNo){
		List list = classifyRecordDao.findByDebtNo(debtNo);
		if(list == null || list.size() == 0) return false;
		return true;
		
	}

	public List<CollateralInfo> findCollateralByCondition(
			Map<String, String> condition, String userId, String orgId) {
		List<CollateralInfo> list = collateralInfoDao.findCustByCondition(condition);
		
		return list;
	}

	public List<GuarantorInfo> findGuarantorByCondition(
			Map<String, String> condition, String userId, String orgId) {
		List<GuarantorInfo> list = guarantorInfoDAO.findCustByCondition(condition);
		
		return list;
	}
}
